package cn._51doit.akka.rpc.我的练习

/**
 * ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃ 　
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 *    　　┃　　　┃神兽保佑
 *    　　┃　　　┃代码无BUG！
 *    　　┃　　　┗━━━┓
 *    　　┃　　　　　　　┣┓
 *    　　┃　　　　　　　┏┛
 *    　　┗┓┓┏━┳┓┏┛
 *    　　　┃┫┫　┃┫┫
 *    　　　┗┻┛　┗┻┛
 *
 * @create: 2021-10-10 15:19
 * @author: 今晚打脑斧
 * @program: Worker
 * @Description:
 *
 **/

import java.util.UUID

import akka.actor.{Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

import scala.concurrent.duration._ //这个包只能手动导入

class Worker(val masterHost: String, val masterPort: Int, val workerMemory: Int, val workerCores: Int) extends Actor {
  val workerId=UUID.randomUUID().toString
  override def preStart(): Unit = {
    //先跟Master建立连接
    val masterRef = context.actorSelection(s"akka.tcp://${Master.MASTER_ACTOR_SYSTEM_NAME}@$masterHost:$masterPort/user/${Master.MASTER_ACTOR_NAME}")
    //向Master发送注册消息（workerId、内存、cpu核数）
    masterRef ! RegisterWorker(workerId, workerMemory, workerCores)
  }

  override def receive: Receive = {
    case RegisteredWorker => {
      //启动一个定时器,定期向Master发送心跳
      import context.dispatcher  //dispatcher 调度员  导入隐式参数
      context.system.scheduler.schedule(0 millisecond,3000 millisecond,sender() , HeartBeat(workerId))
    }
  }
}
object Worker{

  val WORKER_ACTOR_SYSTEM_NAME = "WorkerActorSystem"
  val WORKER_ACTOR_NAME = "WorkerActor"

  def main(args: Array[String]): Unit = {
    val masterHost = args(0)
    val masterPort = args(1).toInt
    val workerHost = args(2)
    val workerPort = args(3).toInt
    val workerMemory = args(4).toInt
    val workerCores = args(5).toInt
    val configStr =
      s"""
         |akka.actor.provider = "akka.remote.RemoteActorRefProvider"
         |akka.remote.netty.tcp.hostname = $workerHost
         |akka.remote.netty.tcp.port = $workerPort
         |""".stripMargin;
    val config = ConfigFactory.parseString(configStr)
    val workerActorSystem = ActorSystem(WORKER_ACTOR_SYSTEM_NAME, config)
    workerActorSystem.actorOf(Props(new Worker(masterHost, masterPort, workerMemory, workerCores)), WORKER_ACTOR_NAME)
  }
}
